import { chromium } from 'playwright';
import { TmallStrategy } from './platforms/tmall/index.js';
import { DouyinStrategy } from './platforms/douyin/index.js';
import { PinduoduoStrategy } from './platforms/pinduoduo/index.js';
import { TaobaoStrategy } from './platforms/taobao/index.js';
import { WeixinStrategy } from './platforms/weixin/index.js';
import { NotificationService } from './services/notification.js';
import { platformConfig, notificationConfig, appConfig, shipmentAccounts, exchangeAccounts, statisticsAccounts } from './config/index.js';
import { accountsConfig } from './config/accounts.js';
import statisticsService from './services/statistics.js';
import { logInfo, logError } from './logger.js';

export class EcommerceAutomationApp {
  constructor() {
    this.browser = null;
    this.context = null;
    this.currentPlatform = null;

    // 初始化通知服务
    this.notificationService = new NotificationService({
      dingtalk: notificationConfig.dingtalk
    });

    // 应用配置
    this.appConfig = appConfig;
  }

  async init(platform) {
    logInfo(`初始化浏览器，平台: ${platform}`);
    // 添加超时控制
    const timeoutPromise = new Promise((_, reject) => {
      setTimeout(() => reject(new Error('浏览器初始化超时')), 60000); // 60秒超时
    });

    try {
      const config = platformConfig[platform];
      let launchOptions = { headless: this.appConfig.headless };
      if (config && config.useLocalChrome && config.chromePath) {
        logInfo(`使用本地Chrome: ${config.chromePath}`);
        launchOptions.executablePath = config.chromePath;
      }
      // 支持 userDataDir（本地用户环境）
      if (config && config.userDataDir) {
        logInfo(`使用本地用户目录: ${config.userDataDir}`);
        this.browser = await Promise.race([
          chromium.launchPersistentContext(config.userDataDir, launchOptions),
          timeoutPromise
        ]);
      } else {
        this.browser = await Promise.race([
          chromium.launch(launchOptions),
          timeoutPromise
        ]);
      }
      logInfo('浏览器已启动');
    } catch (error) {
      logError(`浏览器初始化失败: ${error.message}`);
      throw error;
    }
  }

  async createContext(platform, account) {
    logInfo(`创建浏览器上下文，平台: ${platform}`);
    const config = platformConfig[platform];
    if (!config) {
      logError(`不支持的平台: ${platform}`);
      throw new Error(`不支持的平台: ${platform}`);
    }
    this.currentPlatform = platform;
    // 如果已用 launchPersistentContext，则直接用 browser 作为 context
    if (config && config.userDataDir) {
      this.context = this.browser;
      logInfo('已使用本地用户目录，复用 context');
      return this.context;
    }
    // 兼容账户体系
    const storageState = account?.storageState;
    const useCloudCookie = account?.useCloudCookie;
    const cloudCookieOptions = account?.cloudCookieOptions;
    this.context = await this.browser.newContext({
      defaultTimeout: this.appConfig.defaultTimeout,
      storageState,
      userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'
    });
    // cloud_cookie 支持
    if (useCloudCookie) {
      const { host, uuid, password } = cloudCookieOptions || {};
      if (host && uuid && password) {
        try {
          const { cloud_cookie } = await import('./utils.js');
          const cookies = await cloud_cookie(host, uuid, password);
          await this.context.addCookies(cookies);
          logInfo(`[createContext] 已注入 cloud_cookie，数量: ${cookies.length}`);
        } catch (err) {
          logError(`[createContext] cloud_cookie 注入失败: ${err.message}`);
        }
      } else {
        logWarn('[createContext] cloud_cookie 参数未配置完整，跳过注入');
      }
    }
    logInfo('浏览器上下文已创建');
    return this.context;
  }

  async runRefundProcess(platform, ...params) {
    logInfo(`开始${platform}退款处理任务，参数: ${JSON.stringify(params)}`);
    if (!this.context) {
      logError('请先初始化context');
      throw new Error('请先初始化context');
    }
    let automation;
    switch (platform) {
      case 'tmall':
        automation = new TmallStrategy(this.context);
        break;
      case 'taobao':
        automation = new TaobaoStrategy(this.context);
        break;
      case 'pinduoduo':
        automation = new PinduoduoStrategy(this.context);
        break;
      case 'douyin':
        automation = new DouyinStrategy(this.context);
        break;
      case 'weixin':
        automation = new WeixinStrategy(this.context);
        break;
      default:
        throw new Error('不支持的平台');
    }

    // 构建账户key和店铺名称
    if (params.length > 0 && params[0] && typeof params[0] === 'object' && params[0].key) {
      const accountKey = `${platform}-${params[0].key}`;
      const platformName = platformConfig[platform]?.name || platform;
      const shopName = `${platformName}-${params[0].name}`;
      await automation.processRefunds(accountKey, shopName);
    } else {
      await automation.processRefunds(...params);
    }

    const platformNotifications = platformConfig[platform].notifications;
    if (platformNotifications.enabled && platformNotifications.refundProcess) {
      logInfo(`发送${platform}退款处理通知`);
    }
  }

  async runShipmentReport() {
    logInfo('开始物流报告任务');
    const reports = [];
    for (const item of shipmentAccounts) {
      const [platform, key] = item.split('-');
      const account = (accountsConfig[platform] || []).find(acc => acc.key === key);
      if (!account) {
        logError(`[${platform}] 未找到账户: ${key}`);
        reports.push({ '平台': platform, '错误': `未找到账户: ${key}` });
        continue;
      }
      await this.init(platform);
      await this.createContext(platform, account);
      let report;
      try {
        let strategy;
        const platformName = platformConfig[platform].name;
        const combinedName = `${platformName}-${account.name}`;
        switch (platform) {
          case 'tmall':
            strategy = new TmallStrategy(this.context);
            report = await strategy.getShipmentInfo(combinedName);
            break;
          case 'taobao':
            strategy = new TaobaoStrategy(this.context);
            report = await strategy.getShipmentInfo(combinedName);
            break;
          case 'pinduoduo':
            strategy = new PinduoduoStrategy(this.context);
            report = await strategy.getShipmentInfo(combinedName);
            break;
          case 'douyin':
            strategy = new DouyinStrategy(this.context);
            report = await strategy.getShipmentInfo(combinedName);
            break;
          case 'weixin':
            strategy = new WeixinStrategy(this.context);
            report = await strategy.getShipmentInfo(combinedName);
            break;
          default:
            report = { '平台': platform, '错误': '不支持的平台' };
        }
        reports.push(report);
      } catch (error) {
        logError(`获取${platform}物流信息失败: ${error}`);
        reports.push({ '平台': platform, '错误': error.message || String(error) });
      } finally {
        await this.close();
      }
    }
    await this.notificationService.sendShipmentReport(reports);
  }

  async runRefundStatistics(startTime, endTime) {
    logInfo(`开始退款统计任务，时间范围: ${startTime} - ${endTime}`);
    // 统计所有账户 key
    const accountKeys = statisticsAccounts;
    const statistics = await statisticsService.getRefundStatistics(accountKeys, startTime, endTime);
    // 汇总通知
    await this.notificationService.sendDingTalkMessage({
      customOptions: {
        msgtype: 'markdown',
        markdown: {
          title: '所有账户退款统计',
          text: '#### 昨天退款统计\n' + Object.values(statistics).map(r => {
            // 根据accountKey获取对应的平台和账户名称
            const [platform, key] = r.account.split('-');
            const platformName = platformConfig[platform]?.name || platform;
            const account = (accountsConfig[platform] || []).find(acc => acc.key === key);
            const accountName = account?.name || key;
            return `${platformName}-${accountName}: ${r.count}`;
          }).join('\n'),
        }
      }
    });
    return statistics;
  }

  async runExchangePendingCount(platform, account) {
    logInfo(`[${platform}] 开始换货待处理任务`);
    await this.createContext(platform, account);
    try {
      let count;
      switch (platform) {
        case 'tmall':
          count = await new TmallStrategy(this.context).getExchangePendingCount();
          break;
        case 'taobao':
          count = await new TaobaoStrategy(this.context).getExchangePendingCount();
          break;
        case 'pinduoduo':
          count = await new PinduoduoStrategy(this.context).getExchangePendingCount();
          break;
        case 'douyin':
          count = await new DouyinStrategy(this.context).getExchangePendingCount();
          break;
        case 'weixin':
          count = await new WeixinStrategy(this.context).getExchangePendingCount();
          break;
        default:
          throw new Error('不支持的平台');
      }
      // 修复：处理返回的对象，提取count值
      if (typeof count === 'object' && count.count !== undefined) {
        count = count.count;
      }
      logInfo(`[${platform}] 换货待处理订单数: ${count}`);
      return count;
    } catch (err) {
      logError(`[${platform}] 换货待处理订单数任务异常: ${err.stack || err}`);
      throw err; // 重新抛出错误，让上层方法处理
    } finally {
      await this.close();
    }
  }

  async runExchangePendingCountAll(accounts = exchangeAccounts) {
    logInfo('开始所有平台换货待处理订单数任务');
    const results = [];
    for (const item of accounts) {
      const [platform, key] = item.split('-');
      const account = (accountsConfig[platform] || []).find(acc => acc.key === key);
      if (!account) {
        logError(`[${platform}] 未找到账户: ${key}`);
        results.push({ '平台': platform, '错误': `未找到账户: ${key}` });
        continue;
      }
      await this.init(platform);
      // 不再需要在这里调用createContext，因为runExchangePendingCount会调用
      let result;
      try {
        result = await this.runExchangePendingCount(platform, account);
        // 修复：确保正确格式化结果和店铺名称
        const platformName = platformConfig[platform]?.name || platform;
        const shopName = `${platformName}-${account.name}`;
        results.push({
          '平台': platform,
          'shopName': shopName,
          'count': result
        });
      } catch (err) {
        logError(`[${platform}] 换货待处理订单数任务异常: ${err.stack || err}`);
        const platformName = platformConfig[platform]?.name || platform;
        const shopName = `${platformName}-${account.name}`;
        results.push({ '平台': platform, 'shopName': shopName, '错误': err.message || String(err) });
      } finally {
        await this.close();
      }
    }
    // 修复换行问题，确保使用正确的换行符
    const text = '#### 换货待处理订单数统计\n' + results.map(r => `${r.shopName}: ${r.count ?? r['错误']}`).join('\n');

    await this.notificationService.sendDingTalkMessage({
      customOptions: {
        msgtype: 'markdown',
        markdown: {
          title: '所有平台换货待处理订单数',
          text
        }
      }
    });
    return results;
  }

  async runRefundProcessBatch(accounts) {
    logInfo(`批量退款处理任务，账户: ${JSON.stringify(accounts)}`);
    for (const item of accounts) {
      const [platform, key] = item.split('-');
      const account = (accountsConfig[platform] || []).find(acc => acc.key === key);
      if (!account) {
        logError(`[${platform}] 未找到账户: ${key}`);
        continue;
      }
      await this.init(platform);
      await this.createContext(platform, account);
      try {
        await this.runRefundProcess(platform, account);
      } catch (err) {
        logError(`[${platform}] 退款处理异常: ${err.stack || err}`);
      } finally {
        await this.close();
      }
    }
  }

  async runRefundStatisticsBatch(accounts, startTime, endTime) {
    logInfo(`批量退款统计任务，账户: ${JSON.stringify(accounts)}`);
    const results = [];
    for (const item of accounts) {
      const [platform, key] = item.split('-');
      const account = (accountsConfig[platform] || []).find(acc => acc.key === key);
      if (!account) {
        logError(`[${platform}] 未找到账户: ${key}`);
        results.push({ 'shopName': `${platform}-${key}`, '错误': `未找到账户: ${key}` });
        continue;
      }
      await this.init(platform);
      await this.createContext(platform, account);
      try {
        // 构建完整的账户key，格式为"平台_账户key"
        const fullAccountKey = `${platform}-${key}`;
        const statistics = await statisticsService.getRefundStatistics([fullAccountKey], startTime, endTime);
        const platformName = platformConfig[platform]?.name || platform;
        const shopName = `${platformName}-${account.name}`;
        // 提取统计数量
        const count = statistics[fullAccountKey]?.count || 0;
        results.push({ 'shopName': shopName, 'count': count });
      } catch (error) {
        logError(`[${platform}] 退款统计异常: ${error}`);
        const platformName = platformConfig[platform]?.name || platform;
        const shopName = `${platformName}-${account.name}`;
        results.push({ 'shopName': shopName, '错误': error.message || String(error) });
      } finally {
        await this.close();
      }
    }
    // 修复换行问题，确保使用正确的换行符
    const text = '#### 退款统计\n' + `${results.map(r => `${r.shopName}: ${r.count ?? r['错误']}`).join('\n')}`;

    await this.notificationService.sendDingTalkMessage({
      customOptions: {
        msgtype: 'markdown',
        markdown: {
          title: '所有账户退款统计',
          text
        }
      }
    });
    return results;
  }

  async runTest(platform) {
    logInfo(`[${platform}] 测试方法启动`);
    try {
      switch (platform) {
        case 'tmall':
          await new TmallStrategy(this.context).test();
          break;
        case 'taobao':
          await new TaobaoStrategy(this.context).test();
          break;
        case 'pinduoduo':
          await new PinduoduoStrategy(this.context).test();
          break;
        case 'douyin':
          await new DouyinStrategy(this.context).test();
          break;
        case 'weixin':
          await new WeixinStrategy(this.context).test();
          break;
        default:
          throw new Error('不支持的平台');
      }
    } catch (err) {
      logError(`[${platform}] 测试方法异常: ${err.stack || err}`);
    }
    // 不自动关闭浏览器，便于调试
  }

  async close() {
    if (this.browser) {
      logInfo('关闭浏览器');
      await this.browser.close();
    }
  }
}